iT邦幫忙

2022 iThome 鐵人賽

DAY 2
0

在與諸位CAE老司機正式發車前,我們先來看看如何在VSCode內編寫ANSA,了解何謂deck及速覽一些之後會用的Python小技巧。

VSCode

透過ANSA上方menu,依序按下Tools –> Script –> Script Editor,可開啟內建的編輯器,Script Editor

Script Editor的功能比較陽春,我們一般只做為執行介面或Debug時使用。實際coding,我們會在VSCode內來做。

v22.1.0前,如果想要自動提示來顯示相關函數及參數名的話,需要聯絡原廠或經銷商取得相關package後,自行安裝。

但在v23.0.0之後,已經可以利用ANSA介面安裝獨立的VSCode及其相關提示package。由於ANSA function的名字有時候相當長,對於不是天天使用的function,往往都得回去翻說明文件,現在有了自動提示functionparameter,實在方便許多。

如何安裝可以參考說明文件內的BCS Development Environment with Microsoft Visual Studio Code。我們選擇最直觀的Download from Microsoft安裝,但安裝過程會出現:

:: Setting build path  /tmp
:::: Downloading bcs-dev-env extension
<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1108)>
>> Invalid bcs_dev_env_vsix  

經過一番研究後,發現這個安裝是透過一個Python script。於是我們決定修改~/BETA_CAE_Systems/ansa_v23.0.0/scripts/BuildBcsDevEnv/DevEnvBuilder.py,添加下面兩行程式碼:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

如此,即可順利安裝,以後我們就可以通過Tools > Script > Visual Studio Code來開啟一個有ANSA API自動提示的VSCode開發環境了。

請注意:

  1. 我們使用的作業系統是Ubuntu 20.04.4 LTS,您的作業系統或安裝路徑未必與我們相同,所以可能需要自己摸索一下該檔案的確切位置。
  2. 我們只是純粹分享本身的作法,並未建議如此操作。如果您跟著操作,發生憾事,拜託請不要來找我們XD

Deck

ANSA是多種solver的前處理環境,針對某些操作時,需要明確說明當前指令是針對哪一種solver,所以常常需要給定一個deck參數。由於我們是以LS-DYNA為例,所以我們的deck會固定為constants.LSDYNA

from ansa import constants
deck = constants.LSDYNA

觀察deck,可以發現其值是一個int2,原來ANSA是用不同整數值來代表不同的solver。

Python技巧速覽

Short Circuit

def func(deck=None):
    deck = deck or constants.LSDYNA

如果我們在呼叫func時,不給定deck,那麼deck就會是預設的None。由於bool(None)會是False,所以or會short circuit地選擇constants.LSDYNA做為deck的值。

Unpack

假設func會回傳一個iterable,我們可以用unpack的技巧來取得iterable的任意元素。

如果要取得第一個元素a,可以這麼寫:

a, *_ = func()

如果要取得第二個元素a,可以這麼寫:

_, a, *_ = func()

如果要取得最後一個元素a,可以這麼寫:

*_, a = func()

List Comprehensions

假如我們想對一個iterable中的元素做一些運算,或是過濾掉一些不要的元素,最後再用一個container收集想要的結果,常用的作法如下:

numbers = []
for i in range(10):
    if i % 2:
        numbers.append(i)

但如果使用list comprehensionts可以使code更簡潔,執行速度也會更快。

我們習慣將list comprehensionts拆成三行,第一行是最後經過運算需要放進container的結果,第二行是迴圈,第三行是過濾的條件。

numbers = [i
           for i in range(10)
           if i % 2]

這兩個方法都可以得到相同的結果。

numbers=[1, 3, 5, 7, 9]

Generator Expressions

generator expressionslist comprehensions非常像,只需要將[]改為()即可。但list comprehensions會真的產生listgenerator expression只會產生一個generator

有時候我們只想要取一個iterable中的幾個值,如最大最小等,generator會是一個不錯的選擇。

例如下面的程式碼,我們不需要知道產生的每一個值,而只想知道那些值裡的最小值。

from random import randint

min_ = min(randint(1, 100)
           for _ in range(10))

Sorted

sorted可以將給定的iterable,依照key來進行排列後,回傳一個list

例如下面的程式碼,我們產生一個list,裡面包含十組tupletuple的第一個element代表產生的順序,而第二個element為一個介於1~10的隨機整數。

透過key這個參數,我們可以傳入itemgetter(1, 0),意思是這10tuple比較的邏輯為先比第二個element,如果一樣再比第一個element(Python的index0開始)。

from operator import itemgetter
from random import randint

numbers = [(i, randint(1, 10))
           for i in range(1, 11)]
print(sorted(numbers, key=itemgetter(1, 0)))

其輸出結果為:

[(2, 1), (10, 1), (4, 4), (6, 5), (5, 6), (8, 6), (1, 9), (3, 9), (7, 10), (9, 10)]

Context Manager

利用class來實現context manager需要實作__enter____exit__兩個function

context manager讓我們可以使用with來達到進入及離開某段程式碼時,自動執行__enter____exit__

實務上要實作context manager的機會並不高,我們會在本系列文中後段,學習如何快速產生nodeshellEntity時,實作這個功能。

一個簡單的context manager架構大致如下。

class CtxMgr:
    def __init__(self, a):
        '''
        Do some init if needed
        '''
        self.a = a

    def hello(self):
        print('Hello !')

    def __enter__(self):
        print('__enter__ called')
        return self

    def __exit__(self, exc_type, exc_value, exc_tb):
        print('__exit__ called')
        del self.a


def main():
    with CtxMgr('a') as ctxmgr:
        ctxmgr.hello()
        print(f'{ctxmgr.a=}')  # get 'a' back

    # will raise AttributeError if called outside with
    print(ctxmgr.a)


if __name__ == '__main__':
    main()

我們可以看出一使用with,會先呼叫__enter__ function,接著會是我們自己呼叫的hello function,最後要離開with前,則會呼叫__exit__ function。當在with的範圍內,我們可以取得self.a,但當離開with後,若想再取得self.a,則會產生AttributeError,原因是因為self.a已經在離開with前,被__exit__刪除了。

其輸出結果為:

__enter__ called
Hello !
ctxmgr.a='a'
__exit__ called
AttributeError: 'CtxMgr' object has no attribute 'a'

備註

想快速了解ANSA API的話,可以參考軟體說明文件內Getting Started10 Minutes to ANSA API

Code

本日程式碼傳送門


上一篇
[Day01] - 或躍在淵
下一篇
[Day03] - 建立及刪除Entity
系列文
或躍在淵的CAE: 讓咱們用Python會一會ANSA + LS-DYNA30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言